/* -*-C-*-
 ##############################################################################
 #
 # File:        trice/src/testmem.c
 # RCS:         "@(#)$Revision: 1.17 $ $Date: 94/03/09 11:15:31 $"
 # Description: User routine for doing self test of E1430 module FIFO memory
 # Author:      Doug Passey
 # Created:     
 # Language:    C
 # Package:     E1430
 # Status:      "@(#)$State: Exp $"
 #
 # (C) Copyright 1992, Hewlett-Packard Company, all rights reserved.
 #
 ##############################################################################
 #
 # Please add additional comments here
 #
 # Revisions:
 #
 ##############################################################################
*/

#include "machType.h"

#    include <stdio.h>
#    include <math.h>
#    ifndef DOS_OS
#      include <unistd.h>
#    endif

#include "trice.h"
#include "err1430.h"

#ifndef lint
const char i1430_testmem_fileId[] = "$Header: testmem.c,v 1.17 94/03/09 11:15:31 chriss Exp $";
#endif


#define TABLE_SIZE		1000
/*****************************************************************************
 *
 * Test FIFO memory.  The ADC is set to the rail, and the LO is turned on
 * to produce sine wave data in memory that repeats in a non power of two
 * blocksize.  Memory is scanning, comparing the results with known good
 * results generated previously and put in a table.  The table is generated
 * by the gentable program.
 *
 ****************************************************************************/
SHORTSIZ16 e1430_test_fifo_memory(SHORTSIZ16 la) 
{
  SHORTSIZ16 error;
  SHORTSIZ16 groupID;
  SHORTSIZ16 data;
  LONGSIZ32 memSize;
  register LONGSIZ32 i;
  register SHORTSIZ16 j;
  SHORTSIZ16 x,y;
  char buf1[80];
  SHORTSIZ16 tablesize = 2 * TABLE_SIZE;
  register SHORTSIZ16 reg;

  groupID = e1430_create_module_group(1, &la);
  if(groupID == 0) {
    return(-1);
  }

  error = e1430_reset_module(groupID);
  if(error) return(error);

  /* reset DSP */  
  error = i1430_release_sync(la, MEAS_CONTROL_RESET_DSP_MODE);
  if(error) return(error);

  error = i1430_pull_sync(la, MEAS_CONTROL_RESET_DSP_MODE);
  if(error) return(error);

  error = i1430_release_sync(la, MEAS_CONTROL_NORMAL_MODE);
  if(error) return(error);

  error = e1430_write_register_card(la, E1430_TIMING_SETUP_REG, 0x40);
  if(error) return(error);

  /* continuous mode, complex 16-bit data */
  error = e1430_set_data_format(groupID, E1430_DATA_TYPE_COMPLEX,
		E1430_DATA_SIZE_16, E1430_CONTINUOUS_MODE, 1024L,
		E1430_APPEND_STATUS_OFF);
  if(error) return(error);

  /* zoom to Fs/TABLE_SIZE*/
  error = e1430_set_center_frequency(groupID, 1.0/(FLOATSIZ64)TABLE_SIZE);
  if(error) return(error);

  /* output constant from ADC set to rail */
  error = e1430_write_register_card(la, E1430_ADC_CONTROL_REG, 0x3E);
  if(error) return(error);

  error = e1430_write_register_card(la, E1430_TIMING_SETUP_REG, 0x40);
  if(error) return(error);

  (void)e1430_pause(1.0);		/* wait for front end to settle */

  error = e1430_delete_module_group(groupID);
  if(error) return(error);

  /* start meas */
  error = i1430_start_meas_and_wait(la);
  if(error) return(error);

  error = e1430_read_register_card(la, E1430_HP_SEND_DATA_REG, &x);
  if(error) return(error);
  
  error = e1430_read_register_card(la, E1430_HP_SEND_DATA_REG, &y);
  if(error) return(error);

  for(j=0; j<tablesize; j+=2) {
    if(x == e1430_table[j] && y == e1430_table[j + 1]) break;
  }

  if(j == tablesize) {
    sprintf(buf1, "can't find %X%X in table", (LONGSIZ32)x, (LONGSIZ32)y); 
    error = i1430_Error(ERR1430_FIFO_MEMORY_TEST, buf1, NULL);
    return(error);
  }

  /* get total memory size on module */
  error = e1430_get_status(la, &data);
  if(error) return(error);

  memSize = (LONGSIZ32)(((data & E1430_MEAS_STATUS_MEM_MASK) >> 4) + 1) * 
						(LONGSIZ32)(1L<<22);

  e1430_addr = e1430_get_register_address(la, E1430_HP_SEND_DATA_REG);
  i = 2;

  E1430_TRY 
    /* no bus error catching if E1485 download case 'cuz it screws up the
     * ability to issue a device clear, thus keeping the driver doing 
     * a memory test for 2 minutes with no ability to break
     */

    j = (j+1)%tablesize;
    for(; i<memSize; i++)  {	/* check rest of memory */
      j = (j+1)%tablesize;
      if((reg = iwpeek((USHORTSIZ16 *)e1430_addr)) != e1430_table[j]) {
        E1430_CHECK_BERR
        sprintf(buf1, "expected %X, got %X", (LONGSIZ32)e1430_table[j], 
							(LONGSIZ32)reg); 
        error = i1430_Error(ERR1430_FIFO_MEMORY_TEST, buf1, NULL);
        return(error);
      }
    }
    E1430_CHECK_BERR
  E1430_RECOVER  {
    (void)sprintf(buf1, "FIFO location %lX during memory test", i);
    return(i1430_Error(ERR1430_BUS_ERROR, buf1, NULL));
  }

  return (0);

}

